package com.yj.event_listener;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.provider.CalendarContract;
import android.provider.CallLog;
import android.provider.Telephony;
import android.telecom.Call;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

import androidx.annotation.NonNull;

import com.yj.event_listener.callback.CallStateListener;
import com.yj.event_listener.callback.PhoneCallbackListener;
import com.yj.event_listener.constants.Constants;
import com.yj.event_listener.contentObserver.CalendarContentObserver;
import com.yj.event_listener.contentObserver.PhoneContentObserver;
import com.yj.event_listener.contentObserver.SmsContentObserver;
import com.yj.event_listener.interfaces.NotificationCallback;
import com.yj.event_listener.receiver.CalendarReceiver;
import com.yj.event_listener.receiver.PhoneReceiver;
import com.yj.event_listener.receiver.SmsReceiver;
import com.yj.event_listener.util.LogUtil;
import com.yj.event_listener.util.Utils;

import java.util.HashMap;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

/** EventListenerPlugin */
public class EventListenerPlugin implements FlutterPlugin, MethodCallHandler, NotificationCallback {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;
  private Context context;
  private PhoneReceiver phoneReceiver;
  private CalendarReceiver calendarReceiver;
  private SmsReceiver smsReceiver;
  private TelephonyManager telephonyManager;
  private CallStateListener callStateListener;
  private PhoneCallbackListener phoneCallbackListener;
  private Uri smsUri;
  private SmsContentObserver smsContentObserver;
  private Uri phoneUri;
  private PhoneContentObserver phoneContentObserver;
  private Uri calendarUri;
  private CalendarContentObserver calendarContentObserver;
  private Handler handler;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "event_listener");
    channel.setMethodCallHandler(this);
    context = flutterPluginBinding.getApplicationContext();;
    telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    handler = new Handler(Looper.getMainLooper());
    Utils.isHarmony();
    Utils.isXiaomi();
    LogUtil.d("isHarmony "+Constants.isHarmony);
    LogUtil.d("isXiaomi "+Constants.isXiaomi);

  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    switch (call.method){
      case "getPlatformVersion":
        result.success("Android " + android.os.Build.VERSION.RELEASE);
        break;
      case "startListening":
//        closeReceivers();
        closePhoneListener();
        closeContentObserver();
//        initReceivers();
        initPhoneListener();
        initContentObserver();
        break;
      default:
        result.notImplemented();
        break;
    }
  }

  private void initSmsReceiver(){
    if(smsReceiver == null){
      smsReceiver = new SmsReceiver(this);
    }
    context.registerReceiver(smsReceiver, new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION));
  }

  private void closeSmsReceiver(){
    if(smsReceiver != null){
      context.unregisterReceiver(smsReceiver);
    }
    smsReceiver = null;
  }

  private void initReceivers(){
    if(phoneReceiver == null){
      phoneReceiver = new PhoneReceiver();
    }
    if(smsReceiver == null){
      smsReceiver = new SmsReceiver(this);
    }
    if(calendarReceiver == null){
      calendarReceiver = new CalendarReceiver();
    }
    IntentFilter phoneIntentFilter = new IntentFilter();
    phoneIntentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
    phoneIntentFilter.addAction("android.intent.action.PHONE_STATE_2");
    phoneIntentFilter.addAction("android.intent.action.PHONE_STATE2");
    phoneIntentFilter.addAction("android.intent.action.PHONE_STATE_EXT");
    context.registerReceiver(phoneReceiver, phoneIntentFilter);
    context.registerReceiver(smsReceiver, new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION));
    context.registerReceiver(calendarReceiver, new IntentFilter(CalendarContract.ACTION_EVENT_REMINDER));
  }

  private void closeReceivers(){
    if(phoneReceiver != null){
      context.unregisterReceiver(phoneReceiver);
    }
    if(smsReceiver != null){
      context.unregisterReceiver(smsReceiver);
    }
    if(calendarReceiver != null){
      context.unregisterReceiver(calendarReceiver);
    }
    phoneReceiver = null;
    smsReceiver = null;
    calendarReceiver = null;
  }

  private void initPhoneListener(){
//    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
//      if(phoneCallbackListener == null){
//        phoneCallbackListener = new PhoneCallbackListener();
//      }
//      telephonyManager.registerTelephonyCallback(context.getMainExecutor(), phoneCallbackListener);
//    }else{
      if(callStateListener == null){
        callStateListener = new CallStateListener(context, this);
      }
      telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
//    }
  }

  private void closePhoneListener(){
//    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
//      if(phoneCallbackListener != null){
//        telephonyManager.unregisterTelephonyCallback(phoneCallbackListener);
//      }
//      phoneCallbackListener = null;
//    }else{
    if(callStateListener != null){
      telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
    }
    callStateListener = null;
//    }
  }

  private void initContentObserver(){
    if(Constants.isHarmony || Constants.isXiaomi){
      initSmsReceiver();
    }else{
      smsUri = Telephony.Sms.Inbox.CONTENT_URI;
      if(smsContentObserver == null){
        smsContentObserver = new SmsContentObserver(handler, context, this);
      }
      context.getContentResolver().registerContentObserver(smsUri, false, smsContentObserver);
    }

    phoneUri = CallLog.Calls.CONTENT_URI;
    if(phoneContentObserver == null){
      phoneContentObserver = new PhoneContentObserver(handler, context, this);
    }
    calendarUri = CalendarContract.CalendarAlerts.CONTENT_URI;
    if(calendarContentObserver == null){
      calendarContentObserver = new CalendarContentObserver(handler, context, this);
    }
    context.getContentResolver().registerContentObserver(phoneUri, false, phoneContentObserver);
    context.getContentResolver().registerContentObserver(calendarUri, false, calendarContentObserver);
  }

  private void closeContentObserver(){
    if(Constants.isHarmony || Constants.isXiaomi){
      closeSmsReceiver();
    }else{
      if(smsContentObserver != null){
        context.getContentResolver().unregisterContentObserver(smsContentObserver);
      }
      smsContentObserver = null;
      smsUri = null;
    }

    if(phoneContentObserver != null){
      context.getContentResolver().unregisterContentObserver(phoneContentObserver);
    }
    if(calendarContentObserver != null){
      context.getContentResolver().unregisterContentObserver(calendarContentObserver);
    }

    phoneContentObserver = null;
    phoneUri = null;
    calendarContentObserver = null;
    calendarUri = null;
  }





  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
    handler.removeCallbacksAndMessages(null);
//    closeReceivers();
    closePhoneListener();
    closeContentObserver();
  }

  @Override
  public void onIncomingCall(String title, String text) {
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("title", title);
    map.put("text", text);
    channel.invokeMethod("onIncomingCall", map);
  }

  @Override
  public void onMissedCall(String title, String text) {
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("title", title);
    map.put("text", text);
    channel.invokeMethod("onMissedCall", map);
  }

  @Override
  public void onSms(String title, String text) {
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("title", title);
    map.put("text", text);
    channel.invokeMethod("onSms", map);
  }

  @Override
  public void onCalendar(String title, String text) {
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("title", title);
    map.put("text", text);
    channel.invokeMethod("onCalendar", map);
  }

  @Override
  public void onHangUp() {
    HashMap<String, Object> map = new HashMap<String, Object>();
    map.put("title", "");
    map.put("text", "");
    channel.invokeMethod("onHangUp", map);
  }
}
